package net.play5d.tool.swf_parse {

	import flash.errors.IOError;
	import flash.utils.ByteArray;
	import flash.utils.CompressionAlgorithm;
	import flash.utils.Endian;

	public class SWFFile {

		private var _isParsed:Boolean = false;

		private var _swfByte:ByteArray;

		public 	var type		:String;										// 头标志
		public 	var version		:uint;											// 版本
		public 	var size		:uint;											// SWF 大小
		public 	var width		:uint;											// 宽度
		public 	var height		:uint;											// 高度
		public 	var fps			:uint;											// fps 帧数
		public 	var totalFrames	:uint;											// 主时间轴总帧数
		private var w_h_ruleList:Array;											// 宽高矩阵

		/**
		 * 构造函数
		 * 
		 * @param swfByte ByteArray
		 */
		public function SWFFile(swfByte:ByteArray) {
			_swfByte = swfByte;

			setWHruleList();
		}

		/**
		 * 解析字节
		 */
		public function parseByte():void {
			if (_isParsed || _swfByte == null) {								// 如果解析过了或者数据不存在，就返回
				return;
			}
			_isParsed = true;

			var bin:ByteArray = new ByteArray();								// 头字节
			bin.endian = Endian.LITTLE_ENDIAN;									// 小端字序

			_swfByte.readBytes(bin, 0, 8);										// 读取头 8 个字节，包括了 swf 文件头，版本号，文件大小
			type 	= bin.readUTFBytes(3);										// 前三个字节代表 swf 压缩方式，FWS 未压缩，CWS默认压缩，ZWS lzma压缩
			version = bin[3];													// 第四个字节为版本号
			size 	= bin[7] << 24 | bin[6] << 16 | bin[5] << 8 | bin[4];		// 文件大小是按照 8765 字节顺序排列的 16 进制

			bin.position = 8;													// 移动到第 9 个字节处
			var mainData:ByteArray = new ByteArray();							// 主体字节
			_swfByte.readBytes(mainData);
			if (type == "CWS") {												// 从第九个字节开始启用解压缩
				mainData.uncompress(CompressionAlgorithm.ZLIB);
			}
//			// 优化个锤子，Flash AIR 机制问题！
//			else if (type == "ZWS") {
//				// TODO 有待优化
//				mainData.uncompress(CompressionAlgorithm.LZMA);
//			}
			else if (type != "FWS") {											// 类型既不是 CWS 也不是 FWS 则抛出异常
				throw new IOError("Not an SWF file!");
			}

			bin.writeBytes(mainData, 0, 13);									// 再写 13 个字节，包括 swf 的帧率和总帧数
			var ctrlCode:String = bin[8].toString(16);							// 当前第 8 个字节为控制码
			var w_h_plist:Array = getW_H_RulePosition(w_h_ruleList, ctrlCode);	// 根据控制码获得对应的矩阵
			var len:int = w_h_plist[2];
			var s:String = "";													// 存储宽高数据的字节码
			for (var i:uint = 0; i < len; i++) {
				var temp:String = bin[i + 9].toString(16);
				if (temp.length == 1) {
					temp = "0" + temp;
				}
				s += temp;
			}

			width 	= new Number("0x" + s.substr(w_h_plist[0][0], 4)) / w_h_plist[0][1];
			height 	= new Number("0x" + s.substr(w_h_plist[1][0], 4)) / w_h_plist[1][1];

			var pos:uint = 8 + len;
			fps = bin[pos += 2];												// 宽高数据区结束后再跳 1 字节位置就是 fps
			totalFrames = bin[pos + 2] << 8 | bin[pos + 1];						// 帧数占 2 个字节，从低到高排列，是不是说时间轴的最大帧数就是 65536 ？
		}

		/**
		 * 设置宽高矩阵
		 */
		private function setWHruleList():void {
			w_h_ruleList = [];													// 官方给出的控制码对应字典

			w_h_ruleList[0] = {ctrlCode:"50", position:[[0, 10], [5, 10], 5]};
			w_h_ruleList[1] = {ctrlCode:"58", position:[[1, 40], [6, 10], 6]};
			w_h_ruleList[2] = {ctrlCode:"60", position:[[1, 10], [7, 10], 6]};
			w_h_ruleList[3] = {ctrlCode:"68", position:[[2, 40], [8, 10], 7]};
			w_h_ruleList[4] = {ctrlCode:"70", position:[[2, 10], [9, 10], 7]};
			w_h_ruleList[5] = {ctrlCode:"78", position:[[3, 40], [10, 10], 8]};
			w_h_ruleList[6] = {ctrlCode:"80", position:[[3, 10], [11, 10], 8]};
			w_h_ruleList[7] = {ctrlCode:"88", position:[[2, 40], [12, 10], 9]};
		}

		/**
		 * 得到宽高矩阵的位置数据
		 * 
		 * @param list 
		 * @param str 
		 * @return 
		 */
		private function getW_H_RulePosition(list:Array, str:String):Array {
			for (var i:String in list) {
				if (list[i].ctrlCode == str) {
					break;
				}
			}
			
			return list[i].position;
		}

		public function get swfByte():ByteArray {
			return _swfByte;
		}

		/**
		 * 将类所有关键属性打印
		 * 
		 * @return String
		 */
		public function toString():String {
			return "SWFFile::[" + 
				"type:" 		+ type 			+ "," +
				"version:" 		+ version 		+ "," +
				"size:" 		+ size 			+ "," +
				"width:" 		+ width 		+ "," +
				"height:" 		+ height 		+ "," +
				"fps:" 			+ fps 			+ "," +
				"totalFrames:" 	+ totalFrames 	+
				"]";
		}

		/**
		 * 销毁该类的引用
		 */
		public function destory():void {
			_swfByte.clear();
			_swfByte = null;

			_isParsed = false;
			w_h_ruleList = null;
		}
	}
}